package com.tbit.uqbike.webmanager.controller.tag;

import com.tbit.uqbike.enums.CancelType;
import com.tbit.uqbike.enums.UserType;
import com.tbit.uqbike.object.business.UserInfo;
import com.tbit.uqbike.object.pojo.vo.BatchOperationMsgVO;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.tag.TagBindService;
import com.tbit.uqbike.webmanager.controller.BaseController;
import com.tbit.uqbike.webmanager.dto.TagBindDTO;
import com.tbit.uqbike.webmanager.req.tag.bind.*;
import com.tbit.uqbike.webmanager.req.tag.bind.add.TagByAccountIdBatchReq;
import com.tbit.uqbike.webmanager.req.tag.bind.add.MachineIdBatchTagReq;
import com.tbit.uqbike.webmanager.req.tag.bind.add.MachineNoBatchTagReq;
import com.tbit.uqbike.webmanager.req.tag.bind.add.UserCodeBatchTagReq;
import com.tbit.uqbike.webmanager.resp.tag.TagBindListResp;
import com.tbit.uqbike.webmanager.resp.tag.TagResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 车辆标签绑定
 *
 *
 * @author <a href="mailto:chen.chaoxiong@tbit.com.cn">ChenChaoXiong</a>
 * @since 2024/7/8
 */
@RestController
@Slf4j
@RequestMapping("/tagBind")
public class TagBindController extends BaseController {

    @Autowired
    private TagBindService tagBindService;

        /**
        * 查询车辆标签绑定列表
        *
        * @param req
        * @return
        */
        @RequestMapping("/queryBindList")
        public Result<PageResult<List<TagBindListResp>>> queryBindList(QueryBindListReq req) {

            return Result.success(tagBindService.queryBindListPage(req));
        }

    /**
     * 通过 accountId 批量标记
     * @param req
     * @return
     */
    @PostMapping("/batchTagByAccountId")
    public Result<BatchOperationMsgVO<TagResult>> batchTagBymachineId(@RequestBody @Valid TagByAccountIdBatchReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toTagBindDTO(userInfo);
        return Result.success(tagBindService.tagByAccountId(tagBindDTO));
    }

    /**
     * 通过 machineId 批量标记
     * @param req
     * @return
     */
    @PostMapping("/batchTagByMachineId")
    public Result<BatchOperationMsgVO<TagResult>> batchTagBymachineId(@RequestBody @Valid MachineIdBatchTagReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toTagBindDTO(userInfo);
        return Result.success(tagBindService.tagByMachineId(tagBindDTO));
    }

    /**
     * 通过 machineNo 批量标记
     * @param req
     * @return
     */
    @PostMapping("/batchTagByMachineNo")
    public Result<BatchOperationMsgVO<TagResult>> batchTagByMachineNo(@RequestBody @Valid MachineNoBatchTagReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toAddTagBindDTO(userInfo);
        return Result.success(tagBindService.tagByMachineNo(tagBindDTO));
    }

    /**
     * 通过 userCode 批量标记
     * @param req
     * @return
     */
    @PostMapping("/batchTagByUserCode")
    public Result<BatchOperationMsgVO<TagResult>> batchTagByUserCode(@RequestBody @Valid UserCodeBatchTagReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toTagBindDTO(userInfo);
        return Result.success(tagBindService.tagByUserCode(tagBindDTO));
    }


    /**
     * 通过 machineNo 批量取消标记
     * @param req
     * @return
     */
    @PostMapping("/batchCancelTagByMachineNo")
    public Result<BatchOperationMsgVO<TagResult>> batchCancelTagByMachineNo(@RequestBody @Valid MachineNoBatchTagReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toCancelTagBindDTO(userInfo);
        return Result.success(tagBindService.cancelByMachineNo(tagBindDTO));
    }


    /**
     * 通过 machineId 批量取消标记
     * @param req
     * @return
     */
    @PostMapping("/batchCancelTagByMachineId")
    public Result<BatchOperationMsgVO<TagResult>> batchCancelTagByMachineId(@RequestBody @Valid MachineIdBatchTagReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toCancelTagBindDTO(userInfo);
        return Result.success(tagBindService.cancelByMachineId(tagBindDTO));
    }


    /**
     * 通过 userCode 批量取消标记
     * @param req
     * @return
     */
    @PostMapping("/batchCancelTagByUserCode")
    public Result<BatchOperationMsgVO<TagResult>> batchCancelTagByUserCode(@RequestBody @Valid UserCodeBatchTagReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = req.toCancelTagBindDTO(userInfo);
        return Result.success(tagBindService.cancelByUserCode(tagBindDTO));
    }

    /**
     * 废弃-批量标记/取消标记
     * 调试用 生产请用具体的接口
     * @param req
     * @return
     */
    @Deprecated
    @PostMapping("/batchTag")
    public Result<BatchOperationMsgVO<TagResult>> batchTag(@RequestBody @Valid TagBatchReq req) {
        UserInfo userInfo = fetchUserInfo();
        String type = req.getOprationType();
        if ("add".equals(type)) {
            TagBindDTO tagBindDTO = new TagBindDTO();
            tagBindDTO.setBrandId(req.getBrandId());
            tagBindDTO.setAccountId(req.getAccountId());
            tagBindDTO.setMachineInfoType(req.getMachineInfoType());
            tagBindDTO.setUserType(UserType.MANAGER);

            String machineInfoType = req.getMachineInfoType();
            switch (machineInfoType) {
                case "machineNo":
                    Set<String> machineNos = Optional.ofNullable(req.getMachineInfo())
                                                     .orElse(Collections.emptyList())
                                                     .stream().collect(Collectors.toSet());
                    tagBindDTO.setMachineNos(machineNos);
                    break;
                case "userCode":
                    Set<String> userCodes = Optional.ofNullable(req.getMachineInfo())
                                                     .orElse(Collections.emptyList())
                                                     .stream().collect(Collectors.toSet());
                    tagBindDTO.setUserCodes(userCodes);
                    break;
                case "machineId":
                    Set<Integer> machineIds = Optional.ofNullable(req.getMachineInfo())
                                                      .orElse(Collections.emptyList())
                                                      .stream().map(Integer::parseInt)
                                                      .collect(Collectors.toSet());
                    tagBindDTO.setMachineIds(machineIds);
                    break;
                default:
                    break;
            }
            tagBindDTO.setUserInfo(userInfo);
            Set<Long> tagIds = Optional.ofNullable(req.getTagIds())
                                        .orElse(Collections.emptyList())
                                        .stream().map(Long::parseLong)
                                        .collect(Collectors.toSet());
            tagBindDTO.setTagIds(tagIds);


            return Result.success(tagBindService.batchTag(tagBindDTO));
        } else {


            TagBindDTO tagBindDTO = new TagBindDTO();
            tagBindDTO.setBrandId(req.getBrandId());
            tagBindDTO.setAccountId(req.getAccountId());
            tagBindDTO.setMachineInfoType(req.getMachineInfoType());
            tagBindDTO.setUserType(UserType.MANAGER);
            tagBindDTO.setCancelType(CancelType.MANUAL);

            tagBindDTO.setUserInfo(userInfo);
            Set<Long> tagIds = Optional.ofNullable(req.getTagIds())
                                       .orElse(Collections.emptyList())
                                       .stream().map(Long::parseLong)
                                       .collect(Collectors.toSet());
            tagBindDTO.setTagIds(tagIds);


            String machineInfoType = req.getMachineInfoType();

            switch (machineInfoType) {
                case "tagId":
                    tagBindDTO.setTagIds(tagIds);
                    return Result.success(tagBindService.cancelByTagId(tagBindDTO));

                case "machineNo":
                    Set<String> machineNos = Optional.ofNullable(req.getMachineInfo())
                                                     .orElse(Collections.emptyList())
                                                     .stream().collect(Collectors.toSet());
                    tagBindDTO.setMachineNos(machineNos);
                    return Result.success(tagBindService.cancelByMachineNo(tagBindDTO));
                case "userCode":
                    Set<String> userCodes = Optional.ofNullable(req.getMachineInfo())
                                                    .orElse(Collections.emptyList())
                                                    .stream().collect(Collectors.toSet());
                    tagBindDTO.setUserCodes(userCodes);
                    return Result.success(tagBindService.cancelByUserCode(tagBindDTO));
                case "machineId":
                    Set<Integer> machineIds = Optional.ofNullable(req.getMachineInfo())
                                                      .orElse(Collections.emptyList())
                                                      .stream().map(Integer::parseInt)
                                                      .collect(Collectors.toSet());
                    tagBindDTO.setMachineIds(machineIds);
                    return Result.success(tagBindService.cancelByMachineId(tagBindDTO));
                default:
                    break;
            }



            return Result.success(BatchOperationMsgVO.empty());
        }


    }


    /**
     * 根据标签绑定记录id批量取消标记
     * @param req
     * @return
     */
    @PostMapping("/cancelTag")
    public Result<BatchOperationMsgVO<TagResult>> cancelTag(@RequestBody @Valid CancelByIdReq req) {
        UserInfo userInfo = fetchUserInfo();
        TagBindDTO tagBindDTO = new TagBindDTO();
        tagBindDTO.setUserInfo(userInfo);
        Set<Long> ids = req.getIds().stream().map(Long::parseLong).collect(Collectors.toSet());
        tagBindDTO.setIds(ids);
        tagBindDTO.setCancelType(CancelType.MANUAL);
        tagBindDTO.setUserType(UserType.MANAGER);
        return Result.success(tagBindService.cancelByid(tagBindDTO));
    }


}
